// 导入所需模块
const { OpenAI } = require('openai');
const dotenv = require('dotenv');
const logger = require('../utils/logger'); // 导入日志模块

// 加载环境变量
dotenv.config();

class DeepseekService {
    constructor() {
        // 检查环境变量
        if (!process.env.DEEPSEEK_API_KEY) {
            logger.warn('警告: DEEPSEEK_API_KEY 未配置');
        }

        // 初始化 OpenAI 客户端
        this.client = new OpenAI({
            baseURL: process.env.DEEPSEEK_API_URL || 'https://api.deepseek.com',
            apiKey: process.env.DEEPSEEK_API_KEY
        });
        
        logger.info(`[DeepSeek] 服务初始化完成，API URL: ${process.env.DEEPSEEK_API_URL || 'https://api.deepseek.com'}`);
    }
    
    /**
     * 记录日志
     * @param {string} level - 日志级别
     * @param {string} message - 日志信息
     * @param {Object} data - 额外数据（可选）
     */
    log(level, message, data = null) {
        // 对于敏感信息，不记录完整内容
        let safeData = data ? { ...data } : null;
        
        if (safeData) {
            // 如果包含API密钥，只显示前几位和后几位
            if (safeData.apiKey) {
                safeData.apiKey = `${safeData.apiKey.substring(0, 4)}...${safeData.apiKey.substring(safeData.apiKey.length - 4)}`;
            }
            
            // 如果数据太大，只记录摘要
            const stringified = JSON.stringify(safeData);
            if (stringified.length > 1000) {
                const preview = `${stringified.substring(0, 500)}...（共 ${stringified.length} 字符）`;
                logger[level](`[DeepSeek] ${message} - 数据过大，仅显示摘要: ${preview}`);
                return;
            }
            
            logger[level](`[DeepSeek] ${message} ${JSON.stringify(safeData)}`);
        } else {
            logger[level](`[DeepSeek] ${message}`);
        }
    }

    /**
     * 调用 DeepSeek API 进行文档审核
     * @param {string} content - 需要审核的文档内容
     * @param {string} promptTemplate - 可选的提示词模板
     * @param {string} modelID - 模型ID，默认为deepseek-reasoner
     * @returns {Promise<Object>} - 返回审核结果
     */
    async reviewDocument(content, promptTemplate = null, modelID = "deepseek-reasoner") {
        try {
            // 如果未提供 API 密钥，返回模拟响应
            if (!process.env.DEEPSEEK_API_KEY) {
                this.log('warn', 'API密钥未配置，返回模拟响应');
                return {
                    result: "模拟审核结果：请先配置 API 密钥",
                    thinking: "模拟思考过程"
                };
            }

            // 构建默认提示词模板
            const defaultTemplate = `##角色:你是一位经验丰富的技术文档审核专家。
##任务:请仔细审核以下文档内容，评估其质量、完整性和专业性，并提供改进建议。

请从以下几个方面进行评审：
1. 文档结构与组织：评估文档的整体结构是否清晰、逻辑性强
2. 技术内容准确性：检查技术描述是否准确，术语使用是否正确
3. 完整性：评估文档是否包含所有必要的信息
4. 可读性：考察文档的语言表达、格式和排版
5. 改进建议：提供具体的改进建议

请首先进行深入思考，然后给出评审结果。评审结果应简明扼要，重点突出需要改进的地方。`;

            // 使用提供的模板或默认模板，检查提示模板中是否包含{content}占位符
            let finalPrompt = '';
            if (promptTemplate && promptTemplate.includes('{content}')) {
                // 如果提示词中有{content}占位符，则替换为实际内容
                finalPrompt = promptTemplate.replace('{content}', content);
            } else {
                // 否则按原有方式拼接
                finalPrompt = (promptTemplate || defaultTemplate) + "\n\n审核内容如下：\n\n" + content;
            }

            // 添加长度检查，限制在120K字符以内
            const MAX_PROMPT_LENGTH = 120 * 1024; // 120K字符
            if (finalPrompt.length > MAX_PROMPT_LENGTH) {
                this.log('warn', `提示词过长: ${finalPrompt.length} 字符，超过了 ${MAX_PROMPT_LENGTH} 字符的限制，尝试截断`);
                
                // 计算内容应该保留的长度
                const templateLength = promptTemplate ? promptTemplate.length : defaultTemplate.length;
                const maxContentLength = MAX_PROMPT_LENGTH - templateLength - 100; // 保留额外100字符空间
                
                // 截断内容
                const truncatedContent = content.substring(0, maxContentLength) + 
                    `...\n[内容过长，已截断。原内容共${content.length}字符，已截断为${maxContentLength}字符]`;
                
                // 重新构建提示词
                if (promptTemplate && promptTemplate.includes('{content}')) {
                    finalPrompt = promptTemplate.replace('{content}', truncatedContent);
                } else {
                    finalPrompt = (promptTemplate || defaultTemplate) + "\n\n审核内容如下：\n\n" + truncatedContent;
                }
                
                this.log('warn', `提示词已截断为 ${finalPrompt.length} 字符`);
            }
            
            this.log('debug', '已构建最终提示词', { 
                promptLength: finalPrompt.length,
                useDefaultTemplate: !promptTemplate
            });

            // 构建API调用参数
            const requestParams = {
                model: modelID,  // 使用传入的模型ID
                messages: [
                    { role: "user", content: finalPrompt }
                ],
                max_tokens: 4096  // 设置合理的 token 限制以获取完整响应
            };
            
            // 生成等效的curl命令用于调试
            const baseUrl = process.env.DEEPSEEK_API_URL || 'https://api.deepseek.com';
            const apiKey = process.env.DEEPSEEK_API_KEY;
            let curlCommand = `curl -X POST "${baseUrl}/v1/chat/completions" \\\n`;
            curlCommand += `  -H "Authorization: Bearer ${apiKey}" \\\n`;
            curlCommand += `  -H "Content-Type: application/json" \\\n`;
            curlCommand += `  -d '${JSON.stringify(requestParams).replace(/'/g, "\\'")}'\n`;
            
            // 记录curl命令到日志，方便排查问题
            this.log('info', `DeepSeek API调用的curl命令:\n${curlCommand}`);
            
            // 记录请求开始时间
            const requestStartTime = Date.now();
            
            // 调用 DeepSeek API
            const response = await this.client.chat.completions.create(requestParams);
            
            // 计算请求耗时
            const requestDuration = Date.now() - requestStartTime;
            this.log('info', `API请求完成，耗时: ${requestDuration}ms`);

            // 提取响应结果
            if (response.choices && response.choices.length > 0) {
                const result = {
                    result: response.choices[0].message.content,
                    thinking: response.choices[0].message.reasoning_content || "分析过程已包含在结果中"
                };
                
                this.log('info', '文档审核完成', {
                    resultLength: result.result.length,
                    thinkingLength: result.thinking ? result.thinking.length : 0,
                    finishReason: response.choices[0].finish_reason || 'unknown'
                });
                
                return result;
            } else {
                this.log('error', 'API 响应格式异常：未找到有效的选择项');
                throw new Error('API 响应格式异常');
            }

        } catch (error) {
            this.log('error', `调用 DeepSeek API 失败: ${error.message}`, {
                stack: error.stack,
                name: error.name
            });
            throw error;
        }
    }

    /**
     * 执行聊天完成请求
     * @param {Array} messages - 对话历史消息列表
     * @param {Object} options - 可选参数
     * @returns {Promise<Object>} - 返回聊天响应
     */
    async chatCompletion(messages, options = {}) {
        try {
            const {
                model = "deepseek-chat",
                maxTokens = 2048,
                stream = false
            } = options;

            // 验证消息格式
            if (!Array.isArray(messages) || messages.length === 0) {
                throw new Error('无效的消息格式');
            }
            
            // 构建API调用参数
            const requestParams = {
                model,
                messages,
                max_tokens: maxTokens,
                stream
            };
            
            // 生成等效的curl命令用于调试
            const baseUrl = process.env.DEEPSEEK_API_URL || 'https://api.deepseek.com';
            const apiKey = process.env.DEEPSEEK_API_KEY;
            let curlCommand = `curl -X POST "${baseUrl}/v1/chat/completions" \\\n`;
            curlCommand += `  -H "Authorization: Bearer ${apiKey}" \\\n`;
            curlCommand += `  -H "Content-Type: application/json" \\\n`;
            curlCommand += `  -d '${JSON.stringify(requestParams).replace(/'/g, "\\'")}'\n`;
            
            // 记录curl命令到日志，方便排查问题
            this.log('info', `DeepSeek 聊天API调用的curl命令:\n${curlCommand}`);
            
            // 记录请求开始时间
            const requestStartTime = Date.now();

            // 调用 API
            const response = await this.client.chat.completions.create(requestParams);
            
            // 计算请求耗时
            const requestDuration = Date.now() - requestStartTime;
            this.log('info', `聊天API请求完成，耗时: ${requestDuration}ms`);

            // 处理流式响应
            if (stream) {
                return response;
            }

            // 处理普通响应
            if (response.choices && response.choices.length > 0) {
                return {
                    content: response.choices[0].message.content,
                    reasoning_content: response.choices[0].message.reasoning_content
                };
            } else {
                throw new Error('API 响应格式异常');
            }

        } catch (error) {
            this.log('error', `聊天请求失败: ${error.message}`, {
                stack: error.stack,
                name: error.name
            });
            throw error;
        }
    }

    /**
     * 检查 API 状态
     * @returns {Promise<Object>} - 返回状态信息
     */
    async checkStatus() {
        try {
            return {
                status: "正常",
                api_key: process.env.DEEPSEEK_API_KEY ? "已配置" : "未配置",
                timestamp: Date.now()
            };
        } catch (error) {
            this.log('error', `状态检查失败: ${error.message}`, {
                stack: error.stack,
                name: error.name
            });
            throw error;
        }
    }
}

// 导出服务类
module.exports = DeepseekService; 